home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Language / Compiler / doSymbols.c < prev    next >
C/C++ Source or Header  |  1990-08-16  |  15KB  |  595 lines

  1. /*
  2.  * @(#)doSymbols.c    1.7  1/20/89
  3.  */
  4. #include "assert.h"
  5. #include "error.h"
  6. #include "scan.h"
  7. #include "nodes.h"
  8. #include "symbols.h"
  9. #include "MyParser.h"
  10. #include "sequence.h"
  11. #include "semantics.h"
  12. #include "map.h"
  13. #include "system.h"
  14. #include "flags.h"
  15. #include "trace.h"
  16. #include "opNames.h"
  17. extern void defineGlobal(), resolveGlobal();
  18. extern NodePtr buildSymbol();
  19. extern Map objectTable;
  20. Boolean opNamesResolved = FALSE;
  21.  
  22. typedef struct sIDesc {
  23.   NodePtr        object;
  24.   unsigned int        nestingDepth        :16;
  25.   Boolean        inMonitor        :1;
  26.   Boolean        inInit            :1;
  27.   Boolean        inBlock            :1;
  28.   Boolean        movesThings        :1;
  29.   Boolean        movesSelf        :1;
  30.   unsigned int         unused            :11;
  31.   struct sIDesc        *next;
  32. } IDesc, *IDescPtr;
  33.  
  34. extern int nestingDepth;
  35. static IDescPtr stack = NULL;
  36.  
  37. static void push(p)
  38. NodePtr p;
  39. {
  40.   register IDescPtr t;
  41.   t = (IDescPtr) calloc(1, sizeof(IDesc));
  42.   t->object = p;
  43.   t->nestingDepth = nestingDepth;
  44.   t->next = stack;
  45.   stack = t;
  46. }
  47.  
  48. static void pop()
  49. {
  50.   IDescPtr this;
  51.  
  52.   /* Pop it from the stack. */
  53.   this = stack;
  54.   this->object->b.oblit.f.doesNotMoveArguments = !this->movesThings;
  55.   this->object->b.oblit.f.doesNotMoveSelf = !this->movesSelf;
  56.   stack = this->next;
  57.   free((char *)this);
  58. }
  59.  
  60. static DefineASymbol(p, fKind, isAttached, isMove)
  61. register NodePtr p;
  62. ST_Kinds fKind;
  63. Boolean isAttached, isMove;
  64. {
  65.   assert(p->tag == P_SYMDEF);
  66.   p->b.symdef.symbol = ST_Define(p->b.symdef.ident, fKind, 1);
  67.   if (p->b.symdef.symbol == 0) {
  68.     fprintf(stdout, "\"%s\", line %d: %s redefined.\n",
  69.       currentFileName, p->lineNumber, 
  70.       Ident_Name(p->b.symdef.ident));
  71.     numberOfSemanticErrors++;
  72.   } else {
  73.     p->b.symdef.symbol->isAttached = isAttached;
  74.     p->b.symdef.symbol->isMove = isMove;
  75.   }
  76. }
  77.  
  78. static void DefineAName(p)
  79. NodePtr p;
  80. {
  81.   assert(p->tag == P_OPNAME);
  82. }
  83.  
  84. /*
  85.  * This is called during define symbols, so the symbol field of symbols is
  86.  * not defined yet.  We now compare on the ident field, since these are in
  87.  * the same scope. 
  88.  */
  89.  
  90. static NodePtr findWhereValue(sym, type, where)
  91. NodePtr sym, type, *where;
  92. {
  93.   register NodePtr p, q, w = *where;
  94.   NodePtr resultWW, resultValue;
  95.   Boolean foundIt = FALSE;
  96.   if (type->tag != P_BUILTINLIT ||
  97.       type->b.builtinlit.whichType != KABSTRACTTYPE) return(NN);
  98.   Sequence_For(p, w)
  99.     assert(p->tag == P_WHEREWIDGIT);
  100.     if (foundIt) {
  101.       w->b.children[z__z - 1] = p;
  102.     } else {
  103.       q = p->b.wherewidgit.sym;
  104.       if (q->b.symref.ident == sym->b.symref.ident) {
  105.     foundIt = TRUE;
  106.     resultWW = p;
  107.     if (q->tag == P_SYMDEF) {
  108.       ErrorMessage(q, "Type parameters must be constrained using *>");
  109.       resultValue = NN;
  110.     } else {
  111.       assert(q->tag == P_SYMREF);
  112.       resultValue = resultWW->b.wherewidgit.type;
  113.     }
  114.       }
  115.     }
  116.   Sequence_Next
  117.   if (foundIt) {
  118.     assert(resultWW->tag == P_WHEREWIDGIT);
  119.     w->nChildren --;
  120.     resultWW->b.wherewidgit.type = NULL;
  121.     FreeNode(resultWW);
  122.     return(resultValue);
  123.   } else {
  124.     resultValue = Construct(P_BUILTINLIT, 0);
  125.     resultValue->b.builtinlit.whichType = KANY;
  126.     return(resultValue);
  127.   }
  128. }
  129.  
  130. static void checkFunction(p)
  131. register NodePtr p;
  132. {
  133.   assert(p->tag == P_OPSIG);
  134.   if (p->b.opsig.isFunction) {
  135.     if (Sequence_Length(p->b.opsig.results) != 1) {
  136.       ErrorMessage(p, "Functions must return one result (not %d)",
  137.     Sequence_Length(p->b.opsig.results));
  138.     }
  139.   }
  140. }
  141.  
  142. static void defineSymbols(p)
  143. NodePtr p;
  144. {
  145.   register NodePtr q, r;
  146.   NodePtr whereValue;
  147.   int doExit = 0;
  148.   
  149.   if (p == NN) {
  150.     return;
  151.   } else if ((int)p < 0x200) {
  152.     /* it is probably an input token */
  153.     return;
  154.   } else {
  155.     switch (p->tag) {
  156.       case P_UNAVAILABLEHANDLER:
  157.     doExit = 1;
  158.     ST_EnterNewScope(p, C_UnavailableHandler);
  159.     break;
  160.       case P_VARDECL:
  161.     DefineASymbol(p->b.vardecl.sym, ST_Var, p->b.vardecl.isAttached, FALSE);
  162.     break;
  163.       case P_CONSTDECL:
  164.     DefineASymbol(p->b.constdecl.sym, ST_Const, p->b.constdecl.isAttached, FALSE);
  165.     break;
  166.       case P_PARAM:
  167.     /* unavailables show up here */
  168.     DefineASymbol(p->b.param.sym, ST_Param, p->b.param.isAttached, p->b.param.move);
  169.     break;
  170.       case P_WHEREWIDGIT:
  171.     if ((int)(p->b.wherewidgit.op) == OIDENTITY) {
  172.       assert(p->b.wherewidgit.sym->tag == P_SYMDEF);
  173.       DefineASymbol(p->b.wherewidgit.sym, ST_Const, FALSE, FALSE);
  174.     } else {
  175.       /*
  176.       * We have not a definition but a constraint one here.
  177.       * Just make sure that this is a symbol reference.
  178.       */
  179.       assert((int)p->b.wherewidgit.op == OCONFORMSTO);
  180.       assert(p->b.wherewidgit.sym->tag == P_SYMREF);
  181.     }
  182.     break;
  183.       case P_ENUMLIT:
  184.     NotImplemented(p, "enumeration literals");
  185.     break;
  186.       case P_UNIONLIT:
  187.     NotImplemented(p, "union literals");
  188.     break;
  189.       case P_RECORDLIT:
  190.     NotImplemented(p, "record literals");
  191.     break;
  192.       case P_IMPORT:
  193.     q = p->b.import.syms;
  194.     Sequence_For(r, q)
  195.       DefineASymbol(r, ST_Const, FALSE, FALSE);
  196.     Sequence_Next
  197.     break;
  198.       case P_ATLIT:
  199.     ST_EnterNewScope(p, C_ATLit);
  200.     if (p->b.atlit.name != NN) 
  201.       DefineASymbol(p->b.atlit.name, ST_Const, FALSE, FALSE);
  202.     q = p->b.atlit.ops;
  203.     /* q is a sequence of operation signatures. */
  204.     Sequence_For(r, q)
  205.       ST_EnterNewScope(r, C_OpSig);
  206.       defineSymbols(r);
  207.       checkFunction(r);
  208.       ST_ExitScope();
  209.     Sequence_Next
  210.     ST_ExitScope();
  211.     return;
  212.     /*break;*/
  213.       case P_OPSIG:
  214.     DefineAName(p->b.opsig.name);
  215.     checkFunction(p);
  216.     q = p->b.opsig.params;
  217.     /* q is the parameter list. */
  218.     Sequence_For(r, q)
  219.       assert(r->tag == P_PARAM);
  220.       assert(r->b.param.sym != NN);
  221.       whereValue = 
  222.         findWhereValue(r->b.param.sym, r->b.param.type,
  223.                &p->b.opsig.where);
  224.       if (whereValue != NN) {
  225.         /*
  226.          * This operation has a parameter that is a type.  This means
  227.          * that the operation can only be called at compile time.
  228.          */
  229.         p->b.opsig.mustBeCompilerExecuted = TRUE;
  230.         defineSymbols(whereValue);
  231.       }
  232.       r->b.param.constraint = whereValue;
  233.       DefineASymbol(r->b.param.sym, ST_Param, r->b.param.isAttached, r->b.param.move);
  234.       defineSymbols(r->b.param.type);
  235.     Sequence_Next
  236.     q = p->b.opsig.results;
  237.     /* q is the result list. */
  238.     Sequence_For(r, q)
  239.       assert(r->tag == P_PARAM);
  240.       assert(r->b.param.sym != NN);
  241.       DefineASymbol(r->b.param.sym, ST_Result, r->b.param.isAttached, r->b.param.move);
  242.       defineSymbols(r->b.param.type);
  243.     Sequence_Next
  244.     defineSymbols(p->b.opsig.where);
  245.     return;
  246.     /*break;*/
  247.       case P_SYMDEF:
  248.     break;
  249.       /* enter block */
  250.       case P_OBLIT:
  251.     ST_EnterNewScope(p, C_ObLit);
  252.     assert (p->b.oblit.name != NN);
  253.     DefineASymbol(p->b.oblit.name, ST_Const, FALSE, FALSE);
  254.     Sequence_For(q, p)
  255.       defineSymbols(q);
  256.     Sequence_Next
  257.     ST_ExitScope();
  258.     return;
  259.       case P_OPDEF:
  260.     doExit = 1;
  261.     ST_EnterNewScope(p, C_OpDef);
  262.     break;
  263.       case P_COMP:
  264.     doExit = 1;
  265.     ST_EnterNewScope(p, C_Comp);
  266.     break;
  267.       case P_MONITOR:
  268.     doExit = 1;
  269.     ST_EnterNewScope(p, C_Monitor);
  270.     break;
  271.       case P_IFCLAUSE:
  272.     defineSymbols(p->b.ifclause.exp);
  273.     ST_EnterNewScope(p, C_Block);
  274.     defineSymbols(p->b.ifclause.stats);
  275.     ST_ExitScope();
  276.     return;
  277.       case P_BLOCK:
  278.       case P_ELSECLAUSE:
  279.       case P_LOOPSTAT:
  280.       case P_FAILUREHANDLER:
  281.     doExit = 1;
  282.     ST_EnterNewScope(p, C_Block);
  283.     break;
  284.       }
  285.     Sequence_For(r, p)
  286.       defineSymbols(r);
  287.     Sequence_Next
  288.     if (doExit) ST_ExitScope();
  289.   }
  290. }
  291.  
  292. extern int compareSigs();
  293.  
  294. static int compareDefs(a, b)
  295. NodePtr *a, *b;
  296. {
  297.   assert((*a)->tag == P_OPDEF);
  298.   assert((*a)->b.opdef.sig->tag == P_OPSIG);
  299.   assert((*a)->b.opdef.sig->b.opsig.name->tag == P_OPNAME);
  300.   assert((*b)->tag == P_OPDEF);
  301.   assert((*b)->b.opdef.sig->tag == P_OPSIG);
  302.   assert((*b)->b.opdef.sig->b.opsig.name->tag == P_OPNAME);
  303.   return((*a)->b.opdef.sig->b.opsig.name->b.opname.id -
  304.     (*b)->b.opdef.sig->b.opsig.name->b.opname.id);
  305. }
  306.  
  307. #define MAXOPS 500
  308. static void sortConcreteOps(ct)
  309. register NodePtr ct;
  310. {
  311.   NodePtr opArray[MAXOPS], ops, p;
  312.   register int nextFree = 0, i;
  313.   int stage;
  314.   OID prevOp, thisOp;
  315.  
  316.   assert(ct->tag == P_OBLIT);
  317.   for (stage = 0; stage < 2; stage++) {
  318.     if (stage == 0) {
  319.       ops = ct->b.oblit.monitor;
  320.       if (ops != NULL) {
  321.     assert(ops->tag == P_MONITOR);
  322.     ops = ops->b.monitor.ops;
  323.       }
  324.     } else if (stage == 1) {
  325.       ops = ct->b.oblit.ops;
  326.     }
  327.     Sequence_For(p, ops)
  328.       assert(p->tag == P_OPDEF);
  329.       assert(nextFree < MAXOPS);
  330.       opArray[nextFree++] = p;
  331.     Sequence_Next
  332.   }
  333.   TRACE1(atctsort, 2, "QSorting ct named %s", ATName(ct));
  334.   qsort((char *)opArray, nextFree, sizeof(NodePtr), compareDefs);
  335.   prevOp = 0;
  336.   for (i = 0; i < nextFree; i++) {
  337.     TRACE2(atctsort, 4, "Operation %s has number %d",
  338.       SigName(opArray[i]->b.opdef.sig), i);
  339.     opArray[i]->b.opdef.opNumber = i;
  340.     thisOp = opArray[i]->b.opdef.sig->b.opsig.name->b.opname.id;
  341.     if (prevOp == thisOp) {
  342.       ErrorMessage(ct, "Object \"%s\" multiply defines operation \"%s\"",
  343.     ST_SymbolName(ct->b.oblit.name->b.symdef.symbol),
  344.     ON_Name(prevOp));
  345.     }
  346.     prevOp = thisOp;
  347.   }
  348. }
  349.   
  350. void sortATOps(p)
  351. NodePtr p;
  352. {
  353.   OID prevOp, thisOp;
  354.   register int i;
  355.   if (Sequence_Length(p->b.atlit.ops) > 1) {
  356.     TRACE1(atctsort, 2, "QSorting at named %s", ATName(p));
  357.     qsort((char *)&(p->b.atlit.ops->b.children[0]),
  358.       Sequence_Length(p->b.atlit.ops),
  359.       sizeof(NodePtr),
  360.       compareSigs);
  361.     prevOp = 0;
  362.     for (i = 0; i < Sequence_Length(p->b.atlit.ops); i++) {
  363.       TRACE2(atctsort, 4, "Operation %s has number %d",
  364.     SigName(p->b.atlit.ops->b.children[i]), i);
  365.       thisOp = p->b.atlit.ops->b.children[i]->b.opsig.name->b.opname.id;
  366.       if (prevOp == thisOp) {
  367.     ErrorMessage(p, "Type \"%s\" multiply defines operation \"%s\"",
  368.       ST_SymbolName(p->b.atlit.name->b.symdef.symbol),
  369.       ON_Name(prevOp));
  370.       }
  371.       prevOp = thisOp;
  372.     }
  373.   }
  374. }
  375.  
  376. static void propagateImports(st)
  377. Symbol st;
  378. {
  379.   Symbol ost;
  380.   register IDescPtr idp;
  381.   register NodePtr q;
  382.   for (idp = stack; idp != NULL; idp = idp->next) {
  383.     Sequence_For(q, idp->object->b.oblit.setq)
  384.       assert(q->tag == P_SETQ);
  385.       if (q->b.setq.inner->b.symdef.symbol == st) {
  386.     ost = q->b.setq.outer->b.symref.symbol;
  387.     assert(st->isImport);
  388.     if (idp->inBlock && !idp->inInit) {
  389.       TRACE1(imports, 1, "Symbol %s used outside initially", ST_SymbolName(st));
  390.       st->usedOutsideInitially = TRUE;
  391.     } else {
  392.       TRACE1(imports, 1, "Symbol %s is not used outside initially", ST_SymbolName(st));
  393.     }
  394.     break;
  395.       }
  396.     Sequence_Next
  397.     st = ost;
  398.   }
  399. }
  400.  
  401. static void checkMovedThing(p)
  402. NodePtr p;
  403. {
  404.   Symbol movedThing, stackSymbol;
  405.   if (p->tag == P_SYMREF) {
  406.     movedThing = p->b.symref.symbol;
  407.     stackSymbol = stack->object->b.oblit.name->b.symdef.symbol;
  408.     if (stackSymbol == movedThing) {
  409.       stack->movesSelf = TRUE;
  410.     } else {
  411.       stack->movesThings = TRUE;
  412.     }
  413.   } else {
  414.     stack->movesThings = TRUE;
  415.   }
  416. }
  417.  
  418. static void resolveSymbols(p)
  419. register NodePtr p;
  420. {
  421.   int doExit = 0, saveInBlock;
  422.   register Symbol st;
  423.   register NodePtr q, r, lefts;
  424.     
  425.   if ((int)p < 0x200) return;
  426.   else {
  427.     switch (p->tag) {
  428.       case P_INITDEF:
  429.     stack->inInit = TRUE;
  430.     resolveSymbols(p->b.initdef.body);
  431.     stack->inInit = FALSE;
  432.     return;
  433.       /* enter block */
  434.       case P_ATLIT:
  435.     ST_EnterOldScope(p);
  436.     push(p);
  437.     p->b.atlit.name->b.symdef.symbol->isSelf = TRUE;
  438.     p->b.atlit.name->b.symdef.symbol->value.value = p;
  439.     resolveSymbols(p->b.atlit.name);
  440.     q = p->b.atlit.ops;
  441.     Sequence_For(r, q)
  442.       ST_EnterOldScope(r);
  443.       resolveSymbols(r);
  444.       ST_ExitScope();
  445.     Sequence_Next
  446.     ST_ExitScope();
  447.     sortATOps(p);
  448.     pop();
  449.     return;
  450.     /*break;*/
  451.       case P_SELFLIT:
  452.     p->tag = P_SYMREF;
  453.     assert(stack != NULL);
  454.     q = stack->object->b.oblit.name;
  455.     assert(q->tag == P_SYMDEF);
  456.     p->b.symref = q->b.symdef;
  457.     break;
  458.       case P_OBLIT:
  459.     ST_EnterOldScope(p);
  460.     push(p);
  461.     p->b.oblit.name->b.symdef.symbol->isSelf = TRUE;
  462.     p->b.oblit.name->b.symdef.symbol->value.value = p;
  463.     Sequence_For(q, p)
  464.       resolveSymbols(q);
  465.     Sequence_Next
  466.     ST_ExitScope();
  467.     pop();
  468.     sortConcreteOps(p);
  469.     return;
  470.       case P_SIGNALSTAT:
  471.     if (!stack->inMonitor) ErrorMessage(p, "Signal statements must be in monitors");
  472.     break;
  473.       case P_WAITSTAT:
  474.     if (!stack->inMonitor) ErrorMessage(p, "Wait statements must be in monitors");
  475.     break;
  476.       case P_RETURNSTAT:
  477.       case P_RETURNANDFAILSTAT:
  478.     break;
  479.       case P_CHECKPOINTSTAT:
  480.     if (!stack->inMonitor) ErrorMessage(p, "Checkpoint statements must be in monitors");
  481.     break;
  482.       case P_BLOCK:
  483.     saveInBlock = stack->inBlock;
  484.     stack->inBlock = TRUE;
  485.     ST_EnterOldScope(p);
  486.     Sequence_For(q, p)
  487.       resolveSymbols(q);
  488.     Sequence_Next
  489.     stack->inBlock = saveInBlock;
  490.     ST_ExitScope();
  491.     return;
  492.       case P_OPDEF:
  493.     p->b.opdef.isMonitored = stack->inMonitor;
  494.     ST_EnterOldScope(p);
  495.     doExit = TRUE;
  496.     break;
  497.       case P_IFCLAUSE:
  498.     resolveSymbols(p->b.ifclause.exp);
  499.     ST_EnterOldScope(p);
  500.     resolveSymbols(p->b.ifclause.stats);
  501.     ST_ExitScope();
  502.     return;
  503.       case P_UNAVAILABLEHANDLER:
  504.       case P_COMP:
  505.       case P_ELSECLAUSE:
  506.       case P_LOOPSTAT:
  507.       case P_FAILUREHANDLER:
  508.     ST_EnterOldScope(p);
  509.     doExit = TRUE;
  510.     break;
  511.       case P_MONITOR:
  512.     ST_EnterOldScope(p);
  513.     stack->inMonitor = TRUE;
  514.     resolveSymbols(p->b.monitor.decls);
  515.     resolveSymbols(p->b.monitor.ops);
  516.     resolveSymbols(p->b.monitor.init);
  517.     resolveSymbols(p->b.monitor.recovery);
  518.     stack->inMonitor = FALSE;
  519.     ST_ExitScope();
  520.     return;
  521.       case P_ASSIGNSTAT:
  522.     lefts = p->b.assignstat.left;
  523.     Sequence_For(r, lefts)
  524.       if (r->tag != P_SYMREF) {
  525.         ErrorMessage(r, "Syntactic sugarings require the ':=' operator");
  526.         resolveSymbols(r);
  527.       } else {
  528.         assert (r->tag == P_SYMREF);
  529.         resolveSymbols(r);
  530.         st = ST_Fetch(r->b.symref.symbol);
  531.         if (st != NULL) {
  532.           if (st->itsKind != ST_Var && st->itsKind != ST_Result) {
  533.         ErrorMessage(p, "Assignment to non-variable");
  534.           } else if (st->nestingDepth < stack->nestingDepth) {
  535.         assert(FALSE);
  536.         ErrorMessage(p, "Assignment to imported variable");
  537.           } else if (st->nestingDepth == stack->nestingDepth && !stack->inInit) {
  538.         ErrorMessage(p, "Assignment to non-monitored instance variables can only be made from the initially");
  539.           }
  540.         }
  541.       }
  542.     Sequence_Next
  543.     resolveSymbols(p->b.assignstat.right);
  544.     return;
  545.       case P_SYMREF:
  546.     p->b.symref.symbol = ST_Lookup(p->b.symref.ident, 2);
  547.     if ((st = p->b.symref.symbol) == 0) {
  548.       ErrorMessage(p, "\"%s\" undefined", Ident_Name(p->b.symref.ident));
  549.     } else {
  550. #ifdef OLDSTUFF
  551.       if (st->isImport && stack->inBlock && !stack->inInit)
  552. #else
  553.       if (st->isImport && stack->inBlock)
  554. #endif
  555.         propagateImports(st);
  556.     }
  557.     break;
  558.       case P_CONSTDECL:
  559.     resolveSymbols(p->b.constdecl.type);
  560.     resolveSymbols(p->b.constdecl.value);
  561.     return;
  562.       case P_OPNAME:
  563.     p->b.opname.id = ON_Translate(Ident_Name(p->b.opname.ident));
  564.     break;
  565.       case P_UNFIXSTAT:
  566.     resolveSymbols(p->b.unfixstat.exp);
  567.     checkMovedThing(p->b.unfixstat.exp);
  568.     return;
  569.       case P_MOVESTAT:
  570.       case P_FIXSTAT:
  571.       case P_REFIXSTAT:
  572.     resolveSymbols(p->b.movestat.exp);
  573.     resolveSymbols(p->b.movestat.loc);
  574.     checkMovedThing(p->b.movestat.exp);
  575.     return;
  576.     }
  577.     Sequence_For(q, p)
  578.       resolveSymbols(q);
  579.     Sequence_Next
  580.     if (doExit) ST_ExitScope();
  581.   }
  582. }
  583.  
  584. void initializeSymbols()
  585. {
  586. }
  587.  
  588. void processSymbols(fNodePtr)
  589. NodePtr fNodePtr;
  590. {
  591.   defineSymbols(fNodePtr);
  592.   resolveSymbols(fNodePtr);
  593.   opNamesResolved = TRUE;
  594. }
  595.